import pygame
import sys
import os
from typing import Tuple, Optional, List
from chess.game import Game
from chess.ai import ChessAI
from chess.pieces import Pawn, Knight, Bishop, Rook, Queen, King

# 初始化Pygame
pygame.init()

# 常量定义
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 750
BOARD_SIZE = 640
SQUARE_SIZE = BOARD_SIZE // 8
INFO_PANEL_HEIGHT = WINDOW_HEIGHT - BOARD_SIZE
PIECE_IMAGES = {}  # 棋子图片缓存

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
LIGHT_SQUARE = (240, 217, 181)
DARK_SQUARE = (181, 136, 99)
HIGHLIGHT_COLOR = (102, 204, 255, 150)  # 高亮颜色
MOVE_HIGHLIGHT_COLOR = (106, 148, 106, 150)  # 可移动位置高亮
CHECK_HIGHLIGHT_COLOR = (214, 45, 32, 150)  # 将军高亮

# 设置窗口
window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("国际象棋 - 人机对战")

# 设置字体，尝试不同的中文字体
try:
    # 尝试加载系统字体文件（直接路径）
    font_files = [
        "C:/Windows/Fonts/simhei.ttf",      # Windows 黑体
        "C:/Windows/Fonts/simsun.ttc",      # Windows 宋体
        "C:/Windows/Fonts/msyh.ttc",        # Windows 微软雅黑
        "C:/Windows/Fonts/simkai.ttf",      # Windows 楷体
        "/System/Library/Fonts/STHeiti Light.ttc",  # macOS
        "/System/Library/Fonts/PingFang.ttc",       # macOS
        "/usr/share/fonts/truetype/wqy/wqy-microhei.ttc"  # Linux
    ]
    
    default_font = None
    
    # 先尝试直接加载字体文件
    for font_file in font_files:
        try:
            if os.path.exists(font_file):
                default_font = pygame.font.Font(font_file, 24)
                # 测试字体是否能渲染中文
                test_surface = default_font.render("测试", True, (0, 0, 0))
                print(f"成功加载字体文件: {font_file}")
                break
        except Exception as e:
            print(f"无法加载字体文件 {font_file}: {e}")
            continue
    
    # 如果直接加载失败，尝试使用SysFont
    if default_font is None:
        # 尝试多种中文字体，按优先级排序
        font_names = ["SimHei", "Microsoft YaHei", "SimSun", "KaiTi", "FangSong", "STHeiti", "STXihei", "STFangsong"]
        
        for font_name in font_names:
            try:
                default_font = pygame.font.SysFont(font_name, 24)
                # 测试字体是否能渲染中文
                test_surface = default_font.render("测试", True, (0, 0, 0))
                print(f"成功加载系统字体: {font_name}")
                break
            except Exception as e:
                print(f"无法加载系统字体 {font_name}: {e}")
                continue
    
    # 打印所有可用字体
    # print("系统所有可用字体:", pygame.font.get_fonts())
    
    if default_font is None:
        # 如果所有中文字体都失败，使用默认字体
        default_font = pygame.font.Font(None, 24)
        print("无法加载中文字体，使用默认字体")
except Exception as e:
    print(f"加载字体时出错: {e}")
    default_font = pygame.font.Font(None, 24)  # 如果出错，使用默认字体

title_font = pygame.font.Font(None, 30)  # 标题字体

def load_piece_images():
    """加载棋子图片"""
    pieces = ['wp', 'wn', 'wb', 'wr', 'wq', 'wk', 'bp', 'bn', 'bb', 'br', 'bq', 'bk']
    
    # 使用CairoSVG和Pillow加载SVG图像
    try:
        import cairosvg
        from PIL import Image
        import io
        
        for piece in pieces:
            # 读取SVG文件内容
            svg_path = os.path.join('chess', 'assets', f'{piece}.svg')
            if os.path.exists(svg_path):
                # 转换SVG到PNG
                png_data = cairosvg.svg2png(url=svg_path, output_width=SQUARE_SIZE-10, output_height=SQUARE_SIZE-10)
                # 从PNG数据创建PIL图像
                pil_img = Image.open(io.BytesIO(png_data))
                # 转换PIL图像到Pygame表面
                mode = pil_img.mode
                size = pil_img.size
                data = pil_img.tobytes()
                py_img = pygame.image.fromstring(data, size, mode)
                PIECE_IMAGES[piece] = py_img
            else:
                # 如果文件不存在，创建一个简单的棋子图像
                create_simple_piece_image(piece)
    except ImportError:
        # 如果没有cairosvg库，为每个棋子创建简单的图像
        for piece in pieces:
            create_simple_piece_image(piece)

def create_simple_piece_image(piece):
    """
    创建简单的棋子图像作为备用
    """
    color = WHITE if piece[0] == 'w' else BLACK
    piece_type = piece[1]
    
    # 创建透明表面
    img = pygame.Surface((SQUARE_SIZE - 10, SQUARE_SIZE - 10), pygame.SRCALPHA)
    
    # 绘制棋子底座
    pygame.draw.circle(img, color, (img.get_width() // 2, img.get_height() // 2), img.get_width() // 2 - 5)
    
    # 添加轮廓
    pygame.draw.circle(img, BLACK, (img.get_width() // 2, img.get_height() // 2), img.get_width() // 2 - 5, 2)
    
    # 添加棋子类型文字标识
    text_color = BLACK if piece[0] == 'w' else WHITE
    
    # 根据棋子类型设置符号（既有中文又有英文）
    symbols = {
        'p': {'en': 'P', 'zh': '兵'},
        'r': {'en': 'R', 'zh': '车'},
        'n': {'en': 'N', 'zh': '马'},
        'b': {'en': 'B', 'zh': '象'},
        'q': {'en': 'Q', 'zh': '后'},
        'k': {'en': 'K', 'zh': '王'}
    }
    
    # 直接使用加载好的默认字体（可能已经支持中文）
    try:
        # 先尝试使用默认字体渲染中文
        text = default_font.render(symbols[piece_type]['zh'], True, text_color)
        # 测试渲染是否成功
        if text.get_width() > 0:
            text_rect = text.get_rect(center=(img.get_width() // 2, img.get_height() // 2))
            img.blit(text, text_rect)
            PIECE_IMAGES[piece] = img
            return
    except:
        pass
    
    # 如果默认字体无法渲染中文，使用英文
    text = title_font.render(symbols[piece_type]['en'], True, text_color)
    text_rect = text.get_rect(center=(img.get_width() // 2, img.get_height() // 2))
    img.blit(text, text_rect)
    
    PIECE_IMAGES[piece] = img

def draw_board():
    """绘制棋盘"""
    for row in range(8):
        for col in range(8):
            color = LIGHT_SQUARE if (row + col) % 2 == 0 else DARK_SQUARE
            pygame.draw.rect(window, color, (col * SQUARE_SIZE, row * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE))

def draw_coordinates():
    """绘制坐标标识"""
    # 获取合适的字体
    coord_font = default_font
    if coord_font == pygame.font.Font(None, 24):  # 如果是默认字体，字号调小一点
        coord_font = pygame.font.Font(None, 20)
    
    # 绘制列坐标 (a-h)
    for col in range(8):
        label = chr(97 + col)  # 'a' 到 'h'
        # 根据棋盘底色选择文字颜色
        text_color = BLACK if (7 + col) % 2 == 0 else WHITE
        text = coord_font.render(label, True, text_color)
        # 居中放置
        text_rect = text.get_rect(center=((col + 0.5) * SQUARE_SIZE, BOARD_SIZE - 12))
        window.blit(text, text_rect)
    
    # 绘制行坐标 (1-8)
    for row in range(8):
        label = str(8 - row)  # '8' 到 '1'
        # 根据棋盘底色选择文字颜色
        text_color = BLACK if (row + 0) % 2 == 0 else WHITE
        text = coord_font.render(label, True, text_color)
        # 居中放置
        text_rect = text.get_rect(center=(12, (row + 0.5) * SQUARE_SIZE))
        window.blit(text, text_rect)

def draw_info_panel(game: Game, ai: ChessAI):
    """绘制信息面板"""
    panel_rect = pygame.Rect(0, BOARD_SIZE, WINDOW_WIDTH, INFO_PANEL_HEIGHT)
    pygame.draw.rect(window, (240, 240, 240), panel_rect)
    pygame.draw.line(window, BLACK, (0, BOARD_SIZE), (WINDOW_WIDTH, BOARD_SIZE), 2)
    
    # 使用与create_simple_piece_image相同的方式尝试渲染中文
    chinese_font = None
    chinese_fonts = ["SimHei", "Microsoft YaHei", "SimSun", "KaiTi", "FangSong", "STHeiti"]
    
    for font_name in chinese_fonts:
        try:
            test_font = pygame.font.SysFont(font_name, 24)
            test_surface = test_font.render("测试", True, (0, 0, 0))
            chinese_font = test_font
            break
        except:
            continue
    
    if chinese_font is None:
        chinese_font = title_font
    
    # 当前玩家
    current_player_text = f"当前玩家: {'白方' if game.current_player == 'white' else '黑方'}"
    text = chinese_font.render(current_player_text, True, BLACK)
    window.blit(text, (20, BOARD_SIZE + 20))
    
    # 游戏状态
    game_state = ""
    if game.game_over:
        if game.checkmate:
            game_state = f"将死！{'白方' if game.winner == 'white' else '黑方'}胜利"
        elif game.stalemate:
            game_state = "和棋！"
    elif game.check:
        game_state = "将军！"
    
    if game_state:
        text = chinese_font.render(game_state, True, (214, 45, 32) if "将军" in game_state or "将死" in game_state else BLACK)
        window.blit(text, (300, BOARD_SIZE + 20))
    
    # AI难度
    difficulty_text = f"AI难度: {ai.difficulty}"
    text = chinese_font.render(difficulty_text, True, BLACK)
    window.blit(text, (20, BOARD_SIZE + 60))
    
    # 添加重置按钮
    pygame.draw.rect(window, (200, 200, 200), (650, BOARD_SIZE + 20, 120, 40))
    reset_text = chinese_font.render("重置游戏", True, BLACK)
    reset_rect = reset_text.get_rect(center=(710, BOARD_SIZE + 40))
    window.blit(reset_text, reset_rect)
    
    # 难度选择按钮
    difficulties = ["简单", "普通", "困难"]
    diff_values = ["easy", "normal", "hard"]
    for i, (label, value) in enumerate(zip(difficulties, diff_values)):
        button_color = (150, 150, 150) if ai.difficulty == value else (200, 200, 200)
        button_rect = pygame.Rect(500 + i * 95, BOARD_SIZE + 60, 85, 30)
        pygame.draw.rect(window, button_color, button_rect)
        diff_text = chinese_font.render(label, True, BLACK)
        diff_rect = diff_text.get_rect(center=(button_rect.centerx, button_rect.centery))
        window.blit(diff_text, diff_rect)

def get_piece_image_key(piece):
    """获取棋子图片的键"""
    color_prefix = 'w' if piece.color == 'white' else 'b'
    
    if isinstance(piece, Pawn):
        return color_prefix + 'p'
    elif isinstance(piece, Knight):
        return color_prefix + 'n'
    elif isinstance(piece, Bishop):
        return color_prefix + 'b'
    elif isinstance(piece, Rook):
        return color_prefix + 'r'
    elif isinstance(piece, Queen):
        return color_prefix + 'q'
    elif isinstance(piece, King):
        return color_prefix + 'k'
    
    return None

def draw_pieces(game: Game):
    """绘制棋子"""
    for piece in game.board.get_all_pieces():
        row, col = piece.position
        key = get_piece_image_key(piece)
        
        if key in PIECE_IMAGES:
            img = PIECE_IMAGES[key]
            # 居中显示棋子
            img_rect = img.get_rect(center=((col + 0.5) * SQUARE_SIZE, (row + 0.5) * SQUARE_SIZE))
            window.blit(img, img_rect)

def draw_highlights(game: Game):
    """绘制高亮"""
    # 高亮选中的棋子
    if game.selected_piece:
        row, col = game.selected_piece.position
        highlight = pygame.Surface((SQUARE_SIZE, SQUARE_SIZE), pygame.SRCALPHA)
        highlight.fill(HIGHLIGHT_COLOR)
        window.blit(highlight, (col * SQUARE_SIZE, row * SQUARE_SIZE))
        
        # 高亮可移动位置
        for move in game.valid_moves:
            move_row, move_col = move
            highlight = pygame.Surface((SQUARE_SIZE, SQUARE_SIZE), pygame.SRCALPHA)
            highlight.fill(MOVE_HIGHLIGHT_COLOR)
            window.blit(highlight, (move_col * SQUARE_SIZE, move_row * SQUARE_SIZE))
    
    # 高亮将军状态
    if game.check:
        king_pos = game.board.white_king_position if game.current_player == 'white' else game.board.black_king_position
        row, col = king_pos
        highlight = pygame.Surface((SQUARE_SIZE, SQUARE_SIZE), pygame.SRCALPHA)
        highlight.fill(CHECK_HIGHLIGHT_COLOR)
        window.blit(highlight, (col * SQUARE_SIZE, row * SQUARE_SIZE))

def board_position_to_pixel(position: Tuple[int, int]) -> Tuple[int, int]:
    """
    将棋盘位置转换为像素坐标
    :param position: 棋盘位置（行，列）
    :return: 像素坐标（x, y）
    """
    row, col = position
    return col * SQUARE_SIZE, row * SQUARE_SIZE

def pixel_to_board_position(pos: Tuple[int, int]) -> Optional[Tuple[int, int]]:
    """
    将像素坐标转换为棋盘位置
    :param pos: 像素坐标（x, y）
    :return: 棋盘位置（行，列）或None（如果点击位置不在棋盘内）
    """
    x, y = pos
    if 0 <= x < BOARD_SIZE and 0 <= y < BOARD_SIZE:
        return y // SQUARE_SIZE, x // SQUARE_SIZE
    return None

def handle_click(game: Game, ai: ChessAI, pos: Tuple[int, int]) -> bool:
    """
    处理鼠标点击
    :param game: 游戏对象
    :param ai: AI对手
    :param pos: 鼠标点击位置
    :return: 是否需要AI走子
    """
    # 检查重置按钮
    if BOARD_SIZE <= pos[1] <= BOARD_SIZE + 60 and 650 <= pos[0] <= 770:
        game.reset_game()
        return False
    
    # 检查难度选择按钮
    if BOARD_SIZE + 60 <= pos[1] <= BOARD_SIZE + 90:
        if 500 <= pos[0] < 585:
            ai.set_difficulty('easy')
            return False
        elif 585 <= pos[0] < 670:
            ai.set_difficulty('normal')
            return False
        elif 670 <= pos[0] < 755:
            ai.set_difficulty('hard')
            return False
    
    # 如果游戏结束或者轮到AI走子，则不处理棋盘点击
    if game.game_over or game.current_player != 'white':
        return False
    
    board_pos = pixel_to_board_position(pos)
    if board_pos is None:
        return False
    
    # 如果已经选择了棋子，尝试移动
    if game.selected_piece is not None:
        if board_pos in game.valid_moves:
            game.move_piece(board_pos)
            return True  # 移动成功，轮到AI走子
        else:
            # 如果点击了自己的另一个棋子，切换选择
            piece = game.board.get_piece_at(board_pos)
            if piece is not None and piece.color == game.current_player:
                game.select_piece(board_pos)
            else:
                # 点击了空位或敌方棋子，但不是有效移动，取消选择
                game.selected_piece = None
                game.valid_moves = []
    else:
        # 选择棋子
        game.select_piece(board_pos)
    
    return False

def ai_make_move(game: Game, ai: ChessAI):
    """AI走子"""
    if not game.game_over and game.current_player == 'black':
        # 添加短暂延迟，使AI走子看起来更自然
        pygame.time.delay(500)
        
        move = ai.choose_move(game)
        if move:
            from_pos, to_pos = move
            # 手动选择棋子
            game.select_piece(from_pos)
            # 执行移动
            game.move_piece(to_pos)

def main():
    """主函数"""
    # 加载棋子图片
    load_piece_images()
    
    # 创建游戏对象和AI对手
    game = Game()
    ai = ChessAI(color='black', difficulty='normal')
    
    running = True
    ai_turn = False
    
    while running:
        # 处理事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                # 处理左键点击
                ai_turn = handle_click(game, ai, event.pos)
        
        # AI走子
        if ai_turn:
            ai_make_move(game, ai)
            ai_turn = False
        
        # 绘制
        draw_board()
        draw_coordinates()
        draw_highlights(game)
        draw_pieces(game)
        draw_info_panel(game, ai)
        
        # 更新显示
        pygame.display.flip()
        
        # 控制帧率
        pygame.time.Clock().tick(60)
    
    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main() 